/**
 * Copyright (c) 2015-2015 All Rights Reserved.
 */
package com.zbest.zpay.paycore.biz.action.pay;

import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.zbest.zpay.masterdata.cache.ChannelConfigCache;
import com.zbest.zpay.masterdata.dal.model.ChannelConfigDO;
import com.zbest.zpay.paycore.dal.dao.PayInfoDAO;
import com.zbest.zpay.paycore.dal.dao.PaySubInfoDAO;
import com.zbest.zpay.paycore.dal.model.PayInfoDO;
import com.zbest.zpay.paycore.dal.model.PaySubInfoDO;
import com.zbest.zpay.paycore.integration.exchange.ExchangeClient;
import com.zbest.zpay.paycore.model.PayInfoStatus;
import com.zbest.zpay.paycore.model.PaySubInfoStatus;
import com.zbest.zpay.service.exchange.FinCardPayRequest;
import com.zbest.zpay.service.exchange.FinCardPayResponse;
import com.zbest.zpay.service.exchange.model.FluxInfoStatus;
import com.zbest.zpay.service.exchange.model.FluxKeyEnum;
import com.zbest.zpay.service.paycore.model.PayToolType;
import com.zbest.zpay.service.paycore.model.PaycoreKeyEnum;
import com.zbest.zpay.shared.process.BaseAction;
import com.zbest.zpay.shared.process.ProcessResult;

/**
 * 
 * @author hangdahong
 * @version $Id: PayProcAction.java, v 0.1 2015年6月16日 下午6:07:31 hangdahong Exp $
 */
@Service("payProcessAction")
public class PayProcessAction extends BaseAction {

    @Resource
    private PaySubInfoDAO      paySubInfoDAO;

    @Resource
    private PayInfoDAO         payInfoDAO;

    @Resource
    private ExchangeClient     exchangeClient;

    @Resource
    private ChannelConfigCache channelConfigCache;

    /** 
     * @see com.zbest.zpay.shared.process.BaseAction#perform(com.zbest.zpay.shared.process.ProcessResult)
     */
    @Override
    public void perform(ProcessResult processResponse) {

        PayInfoDO payInfoDO = getValue(PaycoreKeyEnum.PAY_INFO_DO.getCode());

        List<PaySubInfoDO> paySubInfoDOList = getValue(PaycoreKeyEnum.PAY_SUB_INFO_DO_LIST
            .getCode());

        //设置支付订单处理中
        payInfoDAO.updateStatus(payInfoDO.getPayInfoId(), PayInfoStatus.PROCESS.getCode(),
            PayInfoStatus.INITIAL.getCode());

        //TODO，如果以后有新的支付工具，需要注意支付顺序
        for (PaySubInfoDO paySubInfoDO : paySubInfoDOList) {
            if (paySubInfoDO.getPayToolType().equals(PayToolType.CARD_PAY.getCode())) {

                FinCardPayRequest cardPayRequest = buildFinCardPayRequest(paySubInfoDO);
                //设置支付子订单处理中
                paySubInfoDAO.updateStatus(paySubInfoDO.getPaySubInfoId(),
                    PaySubInfoStatus.PROCESS.getCode(), PaySubInfoStatus.INITIAL.getCode());

                FinCardPayResponse cardPayResponse = exchangeClient.exchange(cardPayRequest);
                String fluxInfoStatus = cardPayResponse.getData(FluxKeyEnum.FLUX_STATUS.getCode());

                if (cardPayResponse.isSuccess()
                    && fluxInfoStatus.equals(FluxInfoStatus.SUCCESS.getCode())) {
                    String instSerialNo = cardPayResponse.getData(FluxKeyEnum.INST_SERIAL_NO
                        .getCode());
                    paySubInfoDAO.updateStatusAndInstSerialNo(paySubInfoDO.getPaySubInfoId(),
                        instSerialNo, PaySubInfoStatus.SUCCESS.getCode(),
                        PaySubInfoStatus.PROCESS.getCode());
                }
            } else {
                throw new UnsupportedOperationException("该支付工具不支持");
            }
        }

    }

    /**
     * 
     * @param paySubInfoDO
     * @return
     */
    private FinCardPayRequest buildFinCardPayRequest(PaySubInfoDO paySubInfoDO) {
        ChannelConfigDO channelConfigDO = channelConfigCache.get(paySubInfoDO.getChannelId());
        FinCardPayRequest finAccountPayRequest = new FinCardPayRequest();
        finAccountPayRequest.setAmount(paySubInfoDO.getAmount());
        finAccountPayRequest.setChannelId(channelConfigDO.getChannelId());
        finAccountPayRequest.setCurrency(paySubInfoDO.getCurrency());
        finAccountPayRequest.setPaySubInfoId(paySubInfoDO.getPaySubInfoId());
        finAccountPayRequest.setUserId(paySubInfoDO.getUserId());
        return finAccountPayRequest;
    }
}
